package docker

//docker 镜像讲解


/*

	镜像是什么
	镜像是一种轻量级，可执行的独立软件包，用来打包软件运行环境和基于运行环境开发的软件
	它包含运行某个软件所需的所有内容，包含代码，运行时，库，环境变量和配置文件。
	所有的应用，直接打包docker镜像，就可以直接部署跑起来


	如何得到镜像
		1.从远程仓库下载  docker pull
		2.自己拷贝
		3.自己制作一个镜像dockerFile



	docker镜像加载原理


		UnionFS (联合文件系统) (UFS)

		UnionFS（联合文件系统）：Union文件系统（UnionFS）是一种分层、轻量级并且高性能的文件系统，它支持对文件系统的修改作为一次提交来一层层的叠加，
		同时可以将不同目录挂载到同一个虚拟文件系统下（unite several directorries into a single virtual filesystem）.
		union文件系统是dockerr镜像的基础。镜像可以通过分层来进行继承，基于基础镜像（没有父镜像），可以制作各种具体的应用镜像

		特性：一次同时加载多个文件系统，但从外面看起来，只能看到一个文件系统，联合加载会把各层文件系统叠加起来，这种最终 文件系统会包含所有底层的文件和目录

		举例：联合文件系统用git来内比， git 是版本控制工具

			第一个容器  container
				第一层/版本    centos
				第二层/版本	 golang
				第三层/版本    nginx
				第四层/版本    mysql
				第五层/版本    redis
				第六层/版本    rabbitmq
				第七层/版本	 elasticsearch
				第八层/版本    myapp


			第二个容器 container
				如果需要centos  /不需要再下载


			查看 images/003docker镜像加载原理.png


		------------------docker 镜像加载原理------------------

		docker的镜像实际上由一层一层的文件系统组成，这种层级的文件系统UnionFS.

		bootfs(boot fle system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统，在Docker镜像的最底层是bootfs。
				这一层与我们典型的Linux/Unix系统是一样的，包含boot加载器和内核。
				当boot加载完成之后整个内核就都在内存中了，此时内存的使用权已由bootfs转交给内核，此时系统也会卸载bootfs。
		rootfs (root file system)，在bootfs之上。包含的就是典型Linux系统中的/dev, /proc,/bin, letc等标准目录和文件。
				rootfs就是各种不同的操作系统发行版，比如Ubuntu , Centos等等。

		//bootfs  系统引导加载    内核(kernel)+加载器(bootloader),加载完内核，就会自动删除，把控制权交给内核
			     无论是什么系统，这部分是共用的



		对于一个精简的os， rootfs 可以很小，只需要包含最基本的命令，工具和程序库就可以了，因为底层直接用Host（主机）的kernel（内核）,自己只需要提供rootfs就可以了。
		由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别,因此不同的发行版可以公用bootfs。

		//因为每个容器都是用的是主机的内核，容器内都是命令，所以docker启动非常快。虚拟机是分钟，容器是秒级



		------------------分层的镜像------------------



		docker pull mysql
		[root@VM_0_13_centos docker]#  docker pull mysql
		#//如果不写tag版本，默认就是latest最新
		Using default tag: latest

		latest: Pulling from library/mysql

		//分层下载，docker images镜像的核心
		a076a628af6f: Pull complete
		f6c208f3f991: Pull complete
		88a9455a9165: Pull complete
		406c9b8427c6: Pull complete
		7c88599c0b25: Pull complete
		25b5c6debdaf: Pull complete
		43a5816f1617: Pull complete
		1a8c919e89bf: Pull complete
		9f3cf4bd1a07: Pull complete
		80539cea118d: Pull complete
		201b3cad54ce: Pull complete
		944ba37e1c06: Pull complete

		//签名,防伪标志
		Digest: sha256:feada149cb8ff54eade1336da7c1d080c4a1c7ed82b5e320efb5beebed85ae8c
		Status: Downloaded newer image for mysql:latest

		//真实地址
		docker.io/library/mysql:latest
		//即 docker pull mysql 命令等价于 docker pull docker.io/library/mysql:latest
		[root@VM_0_13_centos docker]#


		//指定版本下载
		docker pull mysql:5.7
		//此处的版本号必须为官方有的版本号，乱写的版本号找不到
		//具体版本登录hub.docker.com网，搜索[镜像名],点击[镜像名],查看具有的版本


		下载mysql，能明显的看到是一层一层的下载

		思考:为什么Docker镜像要采用这种分层的结构呢?
		最大的好处，我觉得莫过于是资源共享了!比如有多个镜像都从相同的Base镜像构建而来，那么宿主机只需在磁盘上保留一份base镜像，同时内存中也只需要加载一份base镜像，这样就可以为所有的容器服务了，而且镜像的每一层都可以被共享。

		查看镜像分层的方式可以通过docker image inspect命令!

		$docker inspect mysql

        .....
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:ad6b69b549193f81b039a1d478bc896f6e460c77c1849a4374ab95f9a3d2cea2",
                "sha256:fba7b131c5c350d828ebea6ce6d52cdc751219c6287c4a7f13a51435b35eac06",
                "sha256:0798f2528e8383f031ebd3c6d351f7d9f7731b3fd12007e5f2fdcdc4e1efc31a",
                "sha256:a0c2a050fee24f87fde784c197a8b3eb66a3881b96ea261165ac1a01807ffb80",
                "sha256:d7a777f6c3a4ded4667f61398eb1f9b380db07bf48876f64d93bf30fb1393f96",
                "sha256:0d17fee8db40d61d9ca0d85bff8b32ef04bbd09d77e02cc67c454c8f84edb3d8",
                "sha256:aad27784b7621a3e58bd03e5d798e505fb80b081a5070d7c822e41606b90a5c0",
                "sha256:1d1f48e448f9b8abb9a2aad1e76d4746b69957882d1ddb9c11115302d45fcbbd",
                "sha256:c654c2afcbba8c359565df63f6ecee333c9cc6abaeaa39838b05b4465a82758b",
                "sha256:118fee5d988ac2057ab66d87bbebd1f18b865fb02a03ba0e23762af5b55b0bd5",
                "sha256:fc8a043a3c7556d9abb4fad3aefa3ab6a5e1c02abda5f924f036c696687d094e",
                "sha256:d67a9f3f65691979bc9e2b5ee0afcd4549c994f13e1a384ecf3e11f83d82d3f2"
            ]
        },
	  ......


	RootFS
       layers 分层，一层一层的下载


------------------

	理解  看图 images/005docker镜像分层原理01.png

	所有的Docker镜像都起始于一个基础镜像层，当进行修改或增加新的内容时，就会在当前镜像层之上，创建新的镜像层。

	举一个简单的例子
		假如基于Ubuntu Linux16.04创建一个新的镜像，这就是新镜像的第一层;
		如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;
		如果继续添加一个安全补丁，就会创建第三个镜像层。

	该镜像当前已经包含3个镜像层，如下图所示(这只是一个用于演示的很简单的例子)。

	//看图 images/005docker镜像分层原理01.png

	举例:看图  images/006docker镜像分层原理02.png
			  images/007docker镜像分层原理03.png


		图03后的一个镜像下载下来，就是6个layer，图二中的文件7是文件5的升级版本，会覆盖文件5




	---------特点---------
	Docker镜像都是只读的，当容器启动时，一个新的可写层被加载到镜像的顶部!
	这一层就是我们通常说的容器层，容器之下的都叫镜像层!

	  images/008docker镜像分层原理04.png

	自己本身的操作都是基于容器层，把自己编写完的和原来的镜像层打包，发布，如果原来有6层，加上自己的程序，就有7层



*/